package seatiger.tomcat.catalina.startup;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXParseException;
import seatiger.tomcat.catalina.Constants;
import seatiger.tomcat.catalina.Container;
import seatiger.tomcat.catalina.Context;
import seatiger.tomcat.catalina.deploy.FilterDef;
import seatiger.tomcat.catalina.deploy.FilterMap;

import javax.servlet.ServletContext;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

/**
 * 一个监听器器，用于 监听context容器的启动，在start过程中完成Digester 对web.xml的解析
 */
public class ContextConfig extends BaseConfig<Context> {
    private static Digester webDigester = createWebDigester();

    public ContextConfig() {
        super(event -> {
            Context co = event.getLifecycle();
            return co;
        });
    }

    private static Digester createWebDigester() {
        Digester webDigester = new Digester();
        webDigester.addRuleSet(new WebRuleSet());
        return webDigester;
    }

    //开始解析web.xml
    @Override
    public void start(Context context) {
        InputStream stream = null;
        ServletContext servletContext = context.getServletContext();
        if (servletContext != null){
            stream = servletContext.getResourceAsStream(Constants.APPLICATION_WEB_XML);
        }
        if (stream == null){
            log(sm.getString("contextConfig.applicationMissing"));
        }
        try{
            webDigester.clear();
            webDigester.push(context);
            webDigester.parse(stream);
        } catch (SAXParseException e) {
            log(sm.getString("contextConfig.applicationParse"), e);
            log(sm.getString("contextConfig.applicationPosition","" + e.getLineNumber(),"" + e.getColumnNumber()));
        } catch (Exception e) {
            log(sm.getString("contextConfig.applicationParse"), e);
        }finally {
            try {
                if (stream != null) {
                    stream.close();
                }
            } catch (IOException e) {
                log(sm.getString("contextConfig.applicationClose"), e);
            }
        }
    }

    @Override
    public void stop(Context context) {
        //将所有的孩子容器移除
        Container[] children = context.findChildren();
        Arrays.stream(children).forEach(child -> context.removeChild(child));

        //起初过滤器定义
        List<FilterDef> filterDefs = context.findFilterDefs();
        filterDefs.forEach(filterDef -> context.removeFilterDef(filterDef));

        //移除过滤器映射
        List<FilterMap> filterMaps = context.findFilterMaps();
        filterMaps.forEach(filterMap -> context.removeFilterMap(filterMap));
        //清理servlet映射关系
        String[] servletMappings = context.findServletMappings();
        Arrays.stream(servletMappings).forEach(servletMapping -> context.removeServletMapping(servletMapping));
    }
}
